package com.czt.mail.limit;

/**
 * @author czt
 * @version 1.0
 * {@desc} 令牌桶限流
 * @date 2024/8/22 14:54
 */
public class TokenBucketLimiter {

    /**
     * 桶的容量
     */
    private final long capacity;

    /**
     * 水流出的速度，即请求处理速度，单位秒
     */
    private final long rate;

    /**
     * 当前令牌数量
     */
    private long tokens;

    private long lastTime = System.currentTimeMillis();

    public TokenBucketLimiter(long capacity, long rate) {
        this.capacity = capacity;
        this.rate = rate;
        this.tokens = capacity;
    }

    /**
     *
     * @return true通过，false限流
     */
    public synchronized boolean limit() {
        long now = System.currentTimeMillis();
        //两次请求间隔内，应该增加的令牌数
        long increasedTokens = Math.round((now - lastTime) / 1000D * rate);
        System.out.println("now=" + now + ",lastTime=" + lastTime + ",increasedTokens=" + increasedTokens);
        tokens = Math.min(capacity, tokens +increasedTokens);
        lastTime = now;
        if (tokens < 1) {
            //水不满继续加水
            return false;
        }else {
            tokens--;
            //水满量
            return true;
        }
    }
}
